package com.yunc.base.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import java.util.Date;
import java.util.HashMap;

/**
 * @author taocongcong
 * @create 2019-10-12 9:34
 */
public class JwtApiTokenUtils {

    private static ThreadLocal<String> threadLocal = new ThreadLocal<>();

    public static final String SECRET = "yuncapi";
    public static final String ISS = "yuxin";

    /**
     * 角色的key
     */
    private static final String USERID_CLAIMS = "userId";

    /**
     * 过期时间是3600秒，既是1个小时
     */
    private static final long EXPIRATION = 3600L;

    /**
     * 选择了记住我之后的过期时间为7天
     */
    private static final long EXPIRATION_REMEMBER = 604800L;

    /**
     * 创建token
     */
    public static String createToken(String userId, String userName, boolean isRememberMe) {
        long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
        HashMap<String, Object> map = new HashMap<>();
        map.put(USERID_CLAIMS, userId);
        return Jwts.builder()
                .signWith(SignatureAlgorithm.HS512, SECRET)  // 签名算法以及密匙
                .setClaims(map)                              // 自定义属性
                .setIssuer(ISS)                              // 签发者
                .setSubject(userName)                        // 主题
                .setIssuedAt(new Date())                    // 签发时间
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))   // 过期时间
                .compact();
    }

    /**
     * 从token中获取用户名
     */
    public static String getUserName(String token){
        return getTokenBody(token).getSubject();
    }

    /**
     * 获取用户ID
     */
    public static String getUserId(String token){
        return (String) getTokenBody(token).get(USERID_CLAIMS);
    }

    /**
     * 是否已过期
     */
    public static boolean isExpiration(String token) {
        try {
            return getTokenBody(token).getExpiration().before(new Date());
        } catch (ExpiredJwtException e) {
            return true;
        }
    }

    private static Claims getTokenBody(String token){
        return Jwts.parser()
                .setSigningKey(SECRET)
                .parseClaimsJws(token)
                .getBody();
    }

    public static String getToken() {
        return threadLocal.get();
    }

    public static void setToken(String token) {
        threadLocal.set(token);
    }

    public static String getCurrentUserName() {
        return getUserName(threadLocal.get());
    }

    public static String getCurrentUserId() {
        return getUserId(threadLocal.get());
    }

    public static void clearToken() {
        // 防止内存泄漏
        threadLocal.remove();
    }
}
